<?php

namespace app\common\model;

use addons\epay\library\Service;
use think\Db;
use think\Exception;
use think\Log;
use think\Model;
use think\Request;

class PayRefund extends Model
{
    protected $name = 'pay_refund';
    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    // 追加属性
    protected $append = [  ];

    private function  setError($error)
    {
        empty($this->error) && $this->error = $error;
    }

    public function hasError()
    {
        return !empty($this->error);
    }

    /**
     * 创建退款数据，并发起申请
     * @param $user_id          会员id
     * @param $resourceType     资源类型  1：商家入驻    2： 技工入驻  3
     * @param $resource_id      资源类型对应ID
     * @param $body             描述，订单标题
     * @param $notifyapi        回调接口，无需带域名
     * @return false|mixed
     * @throws \Exception
     */
    public function createRefundPay($user_id, $resourceType,$resource_id, $body = '退款', $notifyapi = null){
        $out_refund_no = date('YmdHis').rand(1000,9999);
        $payRefundData = [
            'user_id' => $user_id,
            'out_refund_no' => $out_refund_no,
        ];
        //计算退款金额
        $refundAmount = 0;
        switch (intval($resourceType)){
            case 1:    // 商家入驻
                $model = new Store();
                // 未审核、已支付的商家申请
                $info = $model->where(['id'=>['=',$resource_id],'user_id'=>['=',$user_id],'pay_way'=>['<>','30'],'amount'=>['>',0],'state'=>['=','30'],'pay_status' => ['=','20']])->find();
                if(empty($info)){
                    $this->setError('订单错误');
                    return false;
                }
                $refundAmount = $info->amount;
                $field = 'store_id';
                break;
            case 2:    // 技工入驻
                $model = new Artificer();
                // 未审核、已支付的技工申请
                $info = $model->where(['id'=>['=',$resource_id],'user_id'=>['=',$user_id],'pay_way'=>['<>','30'],'amount'=>['>',0],'state'=>['=','30'],'pay_status' => ['=','20']])->find();
                if(empty($info)){
                    $this->setError('技工入驻错误');
                    return false;
                }
                $refundAmount = $info->amount;
                $field = 'artificer_id';
                break;
            default:
                $this->setError('参数resourceType错误');
                return false;
        }
        $payInfo = Pay::where(['user_id'=>['=',$user_id],'pay_state'=>['=','20']])->where('FIND_IN_SET(:id,'.$field.')',['id' => $resource_id])->find();
        if(empty($payInfo)){
            $this->setError('支付信息不存在！');
            return false;
        }
        $payRefundData['amount'] = $refundAmount;
        $payRefundData['pay_id'] = $payInfo->id;
        $payRefundData['pay_type'] = $payInfo->pay_type;
        $payRefundData[$field] = $resource_id;
        $payRefundData['body'] = $body;

        Db::startTrans();
        try {
            $payRefund = self::create($payRefundData);
            if($payRefund->id){
                if($payInfo->pay_type === 'wechat'){
                    $refund = \Yansongda\Pay\Pay::wechat(Service::getConfig($payInfo->pay_type));
                    $param = [
                        'transaction_id' => $payInfo['trade_no'],
                        'out_trade_no' => $payInfo['pay_no'],
                        'out_refund_no' => $out_refund_no,
                        // 'total_fee' => $refundAmount*100,
                        // 'refund_fee' => $refundAmount*100,
                        'total_fee' => 0.01*100,
                        'refund_fee' => 0.01*100,
                        'refund_desc' => $body,
                        'notify_url' => Request::instance()->domain().'/api/index/refundNotify/paytype/'.$payInfo->pay_type,
                        'type' => 'app',
                    ];
                }elseif ($payInfo->pay_type === 'alipay'){
                    $refund = \Yansongda\Pay\Pay::alipay(Service::getConfig($payInfo->pay_type));
                    $param = [
                        'trade_no' => $payInfo['trade_no'],
                        'out_trade_no' => $payInfo['pay_no'],
                        //'refund_amount' => $refundAmount,
                        'refund_amount' => 0.01,
                        'refund_reason' => $body,
                        'out_request_no' => $out_refund_no,
                    ];
                }else{
                    $this->setError('该支付方式退款开发中');
                    return false;
                }
                $data = $refund->refund($param);
                $data = json_decode($data,true);
                if(($payInfo->pay_type == 'alipay') && ($data['code'] == '10000') ){
                    //支付宝退款直接返回结果；微信退款走回调
                    $this->notify($out_refund_no,$data['trade_no']);
                }
            }else{
                throw new \Exception('支付数据失败');
            }
            Db::commit();
        }catch (Exception $e){
            Db::rollback();
            $this->setError($e->getMessage());
            return false;
        }
        return $data;
    }

    /**
     * 回调处理
     * @param $out_refund_no      退款平台内部单号
     * @param $refund_id            退款（支付宝/微信）单号
     * @return false|void
     */
    public function notify($out_refund_no, $refund_id){
        Db::startTrans();
        try {
            $refundPayData = self::where(['out_refund_no'=>['=',$out_refund_no]])->lock(true)->find();
            if(empty($refundPayData)){
                $this->setError('交易号错误');
                return false;
            }
            //业务逻辑 开始
            if($refundPayData->store_id || $refundPayData->artificer_id){
                //商家入驻、技工入驻 退款   改变用户身份，变成普通用户
                if($refundPayData->store_id){
                    $row = Store::get($refundPayData->store_id);
                }
                if($refundPayData->artificer_id){
                    $row = Artificer::get($refundPayData->artificer_id);
                }
                if(empty($row)){
                    $this->setError('入驻审核失败才能退款');
                    return false;
                }
                $row->refund_status = '20';
                $row->refundtime = time();
                $row->save();
                $user = User::get($refundPayData->user_id);
                if($user){
                    $user->identity = '10';
                    $user->save();
                }
            }
            //业务逻辑 结束
            $refundPayData->refund_time = time();
            $refundPayData->status = '30';
            $refundPayData->refund_id = $refund_id;
            $refundPayData->save();

            $pay = Pay::where(['trade_no'=>['=',$refundPayData->transaction_id],'pay_state'=>['in',['20','30']]])->find();
            if($pay){
                // 判断是否是全部退款
                $pay->pay_state = '30';
                $tataoRefundAmount = self::where(['order_id'=>['=',$refundPayData->order_id],'status'=>['=','3']])->sum('amount');
                if($pay->amount <= $refundPayData->amount){
                    $pay->pay_state = '40';
                }
                $pay->save();
            }
            Db::commit();
        }catch (Exception $e){
            Db::rollback();
            $this->setError('回调失败：'.$e->getMessage());
            return false;
        }
    }
}